redis hmget 性能问题 redis hgetall性能优化

您所在的位置:网站首页 jedis hgetall redis hmget 性能问题 redis hgetall性能优化

redis hmget 性能问题 redis hgetall性能优化

2024-07-10 11:13| 来源: 网络整理| 查看: 265

一.引言

Redis 实际使用过程中,由于 redis hgetAll 数据量过于大,导致线上 redis 进程堵塞,读取缓慢影响任务执行效率,改用 hscan 优化。

二.Case分析1.hgetAll 为什么慢

hgetAll 获取指定 key 的全部 hash 结果,时间复杂度 O(n) ,hash 的 key 越多,当 kv 值不多时 hgetAll 非常好用,但是使用 hgetAll 获取的数据量越大,获取的性能越低。与之类似的是 hdel,随着 key 的增加,获取的时间并不是完全的线性增加,而是可能出现翻倍的情况。因此对于高并发的场景,要尽量避免在大数据上进行 hgetAll,hdel,emembers 等操作。

redis hmget 性能问题 redis hgetall性能优化_scala

2.hscan 怎么代替

scan,hscan 是增量式迭代命令,通过游标进行分段式读取,负载压力从而不会堵塞 redis 线程,但是速度会慢于 hgetall。hscan 主要用到 ScanParams,通过 ScanParams.count() 方法可以设置每次迭代获取的数据量,假设hgetAll redis read峰值很高,正常值 200,那就可以设定 count(200)。还有一个参数是 SCAN_POINTER_START,该字符型变量标记当前获取的游标,当游标为"0"时,代表全部元素获取完毕。

Tips:

hscan 每次返回的结果可能存在重复,最后整合所有结果时需要自己去重

3.还有方法减小压力嘛

A.redis.dump

redis.dump(key) 可以获取对应元素序列化后的内容 Array[Byte],可以使用 redis 相同的序列化协议进行反序列化,从而避免在 redis 客户端执行序列化,缩短时间

B.拆分 key-value

将原始 HashMap 分布在多个 key 上,缩小每个 Hmap 的大小,整体的数据量变化不大

C.加机器

和拆分的思想类似,可以提高 redis 数量,通过 redis-pool 减轻单点 redis 的压力

D.数据量很大

转存 Hbase

三.hscan 实现代码

A.ScanParams 初始化每次迭代的数量,count 为迭代量

B.SCAN_POINTER_START 为计数游标,标记为"0"时代表全部迭代结束

C.scanResult.getResult() 返回 util.Map.Entry 接口,此接口为泛型,定义为Entry,转换后存入 map 即可

def redisHScan(jedis: Jedis, key: String, count: Int = 100): mutable.HashMap[String, String] = { val infoMap = mutable.HashMap[String, String]() val scanParams = new ScanParams().count(count) var cur = redis.clients.jedis.ScanParams.SCAN_POINTER_START var cycleIsFinished = false while (!cycleIsFinished) { val scanResult = jedis.hscan(key, cur, scanParams) val result = scanResult.getResult.asScala.map(entry => (entry.getKey, entry.getValue)) infoMap ++= result cur = scanResult.getStringCursor if (cur == "0") cycleIsFinished = true } infoMap } val scanMap = redisHScan(redis, key, 100000)

下面对一个 55w+ key 的 HashMap 进行读取测试:

redis hmget 性能问题 redis hgetall性能优化_Redis_02

 

redis hmget 性能问题 redis hgetall性能优化_scala_03

四.总结

hgetAll 获取大 key 时可以用 hscan 替代,但也需要注意 count 的大小和 Redis 具体的压力,除此之外还有一点需要注意,由于 hscan 是迭代获取执行,所以可能存在数据不一致的情况,获取靠前的数据时,靠后的数据已被修改,这时候会出现先到的数据为老数据,后到的数据为新数据的情况。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3